<?php

/**
 * 基于左右值排序的无限分类算法
 * 数据库结果为
 CREATE TABLE om_catagory (
 CatagoryID int(10) unsigned NOT NULL auto_increment,
 Name varchar(50) default '',
 Lft int(10) unsigned NOT NULL default '0',
 Rgt int(10) unsigned NOT NULL default '0',
 PRIMARY KEY (CatagoryID),
 KEY lft (lft),
 KEY rgt (rgt)
 )   *
 */


class Category {
	
	
    private $db;

    private $tablefix;


    /**
     * Detail description.
     * 构造函数,引入数据库操作类函数
     * @param         $db
     * @access         public
     * @return         void
     */

    public function __construct($db){		
		$this->db=$db;
		$this->tablefix='om_';
	}// end func


    /**
     * Short description.
     * 增加新的分类
     * Detail description
     * @param         none
     * @since         1.0
     * @access         private
     * @return         void
     */
   public function addsort($CatagoryID,$SortName) {
        if($CatagoryID==0) {
            $Lft=0;
            $Rgt=1;
        }else {
            $Result=$this->checkcatagory($CatagoryID);
            //取得父类的左值,右值
            $Lft=$Result[0]['Lft'];
            $Rgt=$Result[0]['Rgt'];
            $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+2 WHERE `Lft`>$Rgt");
            $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+2 WHERE `Rgt`>=$Rgt");
        }

        //插入
        if($this->db->query("INSERT INTO `".$this->tablefix."catagory` SET `Lft`='$Rgt',`Rgt`='$Rgt'+1,`Name`='$SortName'")) {
            return 1;
        }else {
            return -1;
        }
    } // end func



    /**
     * Short description.
     * 删除类别
     * Detail description
     * @param         none
     * @global         none
     * @since         1.0
     * @access         private
     * @return         void
     */
   public function deletesort($CatagoryID) {
    //取得被删除类别的左右值,检测是否有子类,如果有就一起删除
        $Result=$this->checkcatagory($CatagoryID);
        $Lft=$Result[0]['Lft'];
        $Rgt=$Result[0]['Rgt'];
        //执行删除
        if($this->db->query("DELETE FROM `".$this->tablefix."catagory` WHERE `Lft`>=$Lft AND `Rgt`<=$Rgt")) {
            $Value=$Rgt-$Lft+1;
            //更新左右值
            $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value WHERE `Lft`>$Lft");
            $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value WHERE `Rgt`>$Rgt");
            return 1;
        }else {
            return -1;
        }
    } // end func


    /**
     * Short description.
     * 1,所有子类,不包含自己;2包含自己的所有子类;3不包含自己所有父类4;包含自己所有父类
     * Detail description
     * @param         none
     * @global         none
     * @since         1.0
     * @access         private
     * @return         void
     */
   public  function getcatagory($CatagoryID,$type=1) {
        $Result=$this->checkcatagory($CatagoryID);
        $Lft=$Result[0]['Lft'];
        $Rgt=$Result[0]['Rgt'];
        $SeekSQL="SELECT * FROM `".$this->tablefix."catagory` WHERE ";
        switch ($type) {
            case "1":
                $condition="`Lft`>$Lft AND `Rgt`<$Rgt";
                break;
            case "2":
                $condition="`Lft`>=$Lft AND `Rgt`<=$Rgt";
                break;
            case "3":
                $condition="`Lft`<$Lft AND `Rgt`>$Rgt";
                break;
            case "4":
                $condition="`Lft`<=$Lft AND `Rgt`>=$Rgt";
                break;
            default :
                $condition="`Lft`>$Lft AND `Rgt`<$Rgt";
        }
        $SeekSQL.=$condition." ORDER BY `Lft` ASC";
        $Sorts=$this->getrow($SeekSQL);
        return $Sorts;
    } // end func



    /**
     * Short description.
     * 取得直属父类
     * Detail description
     * @param         none
     * @access         private
     * @return         void
     */
   public function getparent($CatagoryID) {
        $Parent=$this->getcatagory($CatagoryID,3);
        return $Parent;
    } // end func
    /**
     * Short description.
     * 移动类,如果类有子类也一并移动
     * Detail description
     * @param         none
     * @access         private
     * @return         void
     */
   public function movecatagory($SelfCatagoryID,$ParentCatagoryID) {
        $SelfCatagory=$this->checkcatagory($SelfCatagoryID);
        $NewCatagory=$this->checkcatagory($ParentCatagoryID);

        $SelfLft=$SelfCatagory[0]['Lft'];
        $SelfRgt=$SelfCatagory[0]['Rgt'];
        $Value=$SelfRgt-$SelfLft;
        
        //取得所有分类的ID方便更新左右值
        $CatagoryIDS=$this->getcatagory($SelfCatagoryID,2);
        foreach($CatagoryIDS as $v) {
            $IDS[]=$v['CatagoryID'];
        }
        $InIDS=implode(",",$IDS);

        $ParentLft=$NewCatagory[0]['Lft'];
        $ParentRgt=$NewCatagory[0]['Rgt'];
        /*print_r($InIDS);
        print_r($NewCatagory);
        print_r($SelfCatagory);
        exit;*/
        if($ParentRgt>$SelfRgt) {
            $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value-1 WHERE `Lft`>$SelfRgt AND `Rgt`<=$ParentRgt";
            $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value-1 WHERE `Rgt`>$SelfRgt AND `Rgt`<$ParentRgt";
            $TmpValue=$ParentRgt-$SelfRgt-1;
            $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$TmpValue,`Rgt`=`Rgt`+$TmpValue WHERE `CatagoryID` IN($InIDS)";
        }else {
            $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$Value+1 WHERE `Lft`>$ParentRgt AND `Lft`<$SelfLft";
            $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+$Value+1 WHERE `Rgt`>=$ParentRgt AND `Rgt`<$SelfLft";
            $TmpValue=$SelfLft-$ParentRgt;
            $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$TmpValue,`Rgt`=`Rgt`-$TmpValue WHERE `CatagoryID` IN($InIDS)";
        }
        $this->db->query($UpdateLeftSQL);
        $this->db->query($UpdateRightSQL);
        $this->db->query($UpdateSelfSQL);
        return 1;
    } // end func


    /**
     * Short description.
     *
     * Detail description
     * @param         none
     * @access         private
     * @return         void
     */
   public function checkcatagory($CatagoryID) {
    //检测父类ID是否存在
        $SQL="SELECT * FROM `".$this->tablefix."catagory` WHERE `CatagoryID`='$CatagoryID' LIMIT 1";
        $Result=$this->getrow($SQL);
        if(count($Result)<1) {
            $this->referto("父类ID不存在,请检查","javascript :history.back(1)",3);
        }
        return $Result;
    } // end func


    /**
     * Short description.
     *
     * Detail description
     * @param         none
     * @access         private
     * @return         void
     */
   public function getrootid() {
        $Query="SELECT * FROM`".$this->tablefix."catagory` ORDER BY `Lft` ASC LIMIT 1";
        $RootID=$this->getrow($Query);
        if(count($RootID)>0) {
            return $RootID[0]['CatagoryID'];
        }else {
            return 0;
        }
    } // end func


    /**
     *
     * Detail description
     * @param         none
     * @access         private
     * @return         String
     */
   public function referto($msg,$url,$sec) {
        echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">";
        echo "<meta http-equiv=refresh content=$sec;URL=$url>";
        if(is_array($msg)) {
            foreach($msg as $key=>$value) {
                echo $key."=>".$value."<br>";
            }
        }else {
            echo $msg;
        }
        exit;
    } // end func

	/**
     *
     * Detail description
     * @param         none
     * @access         private
     * @return         void
     */
	 public function getrow($SQL){
		return $this->db->query($SQL);
	 }// end func
	 
	 /**
     * Detail description
     * @param         none
     * @access         public 
     * @return         Array
	 */
	 public function getview(){
	 	$sql = "SELECT `node`.name,(COUNT(`parent`.name)-1) AS depth FROM om_catagory AS `node`,om_catagory AS `parent` WHERE `node`.lft BETWEEN `parent`.lft AND `parent`.rgt GROUP BY `node`.name ORDER BY `node`.lft";
	 	$category = $this->db->query($sql);
	 	foreach ($category as $value) {
	 		if ($value['depth']) {
	 			//echo $value['name'].'<br />';
	 			if($value['path']>1){
	 				echo str_repeat('|-',$value['depth'])."<span style='display:none;'>".$value['name'].'</span>'.'<br/>';
	 			}else{
	 				echo str_repeat('|-',$value['depth'])."<span>".$value['name'].'</span>'.'<br/>';
	 			}
	 		}
	 	}
	 	
	 	
	 }// end func
	 

} // end class
	
?>